package com.example.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.example.common.constant.AccountIdentityConstant;
import com.example.common.constant.CommonConstant;
import com.example.entity.UserAuth;
import com.example.entity.UserInfo;
import com.example.service.UserService;
import com.example.service.WxService;
import com.example.vo.WxUserInfoVO;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

@Service("wxService")
public class WxServiceImpl implements WxService {

    /**
     * @description WxMaService
     */
    @Resource
    private WxMaService wxMaService;

    /**
     * @description userService
     */
    @Resource
    private UserService userService;

    /**
     * @description     根据返回code获取用户unionId或openId并存储
     * @param code      用户登录凭证（有效期五分钟）
     * @param session   http会话
     */
    @Override
    public void code(String code, HttpSession session) throws WxErrorException {
        // 1、code换取session_key接口的响应
        WxMaJscode2SessionResult sessionInfo =  wxMaService.getUserService().getSessionInfo(code);
        // 将 用户微信sessionKey, openId, unionId 放进session 中。以便在后台其他地方使用
        session.setAttribute(CommonConstant.SESSION_KEY, sessionInfo.getSessionKey());
        session.setAttribute(CommonConstant.OPEN_ID, sessionInfo.getOpenid());
        session.setAttribute(CommonConstant.UNION_ID, sessionInfo.getUnionid());

        // 2、根据 微信openId 查询数据库 ==> 判断用户是否已经存在
        UserAuth openIdAuth = userService.findByIdentifier(sessionInfo.getOpenid());

        if (openIdAuth == null) {
            UserInfo userInfo = UserInfo.builder().build();
            // 3、先保存 用户基本信息
            if (userService.saveUserInfo(userInfo)) {

                // 4.1 保存用户微信openId
                userService.saveUserAuth(
                        new UserAuth(userInfo.getId(), AccountIdentityConstant.WX_MA_OPEN_ID, sessionInfo.getOpenid()));

                // 4.2  保存用户微信unionId
                userService.saveUserAuth(
                        new UserAuth(userInfo.getId(), AccountIdentityConstant.WX_UNION_ID, sessionInfo.getUnionid()));
            }
        } else {
            session.setAttribute(CommonConstant.USER_ID, openIdAuth.getUser_id());
        }

    }

    /**
     * @description         微信用户信息录入
     * @param wxUserInfoVO  微信用户信息入参
     * @param session       http会话
     */
    @Override
    public void save(WxUserInfoVO wxUserInfoVO, HttpSession session) {
        // 解密微信用户信息
        WxMaUserInfo wxMaUserInfo = wxMaService.getUserService().getUserInfo(
                (String) session.getAttribute(CommonConstant.SESSION_KEY),
                wxUserInfoVO.getEncryptedData(), wxUserInfoVO.getIv());

        String userId = null;

        // 根据 微信openId 查询数据库 ==> 判断用户是否已经存在
        UserAuth openIdAuth = userService.findByIdentifier(wxMaUserInfo.getOpenId());
        if (openIdAuth != null) {
            // 保存用户信息
            UserInfo userInfo = initUserInfo(wxMaUserInfo);
            userInfo.setId(openIdAuth.getUser_id());
            userService.updateUserInfo(userInfo);
        }
        session.setAttribute(CommonConstant.USER_ID, userId);
        session.setAttribute(CommonConstant.USER_NAME, wxMaUserInfo.getNickName());

    }

    /**
     * @description         微信用户信息转换成系统用户信息
     * @param wxMaUserInfo  微信用户信息
     * @return              系统用户信息
     */
    private UserInfo initUserInfo(WxMaUserInfo wxMaUserInfo) {
        return UserInfo.builder()
                .nick_name(wxMaUserInfo.getNickName())
                .gender(Integer.valueOf(wxMaUserInfo.getGender()))
                .languages(wxMaUserInfo.getLanguage())
                .city(wxMaUserInfo.getCity())
                .province(wxMaUserInfo.getProvince())
                .country(wxMaUserInfo.getCountry())
                .head_url(wxMaUserInfo.getAvatarUrl())
                .build();
    }




}
